home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / demos / demobook / file.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  58.8 KB  |  1,895 lines

  1. /*
  2.  * Copyright (C) 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. #include <stdio.h>
  18. #include <unistd.h>
  19. #include "exinterfmotif.h"
  20. #include <math.h>
  21. #include <string.h>
  22. #include "exbookglo.h"
  23. #include "exglobals.h"
  24.  
  25. extern struct indexlist *(find_keyword_int() );
  26. extern struct indexlist *(add_keyword() );
  27. extern struct indexlist *find_keyword();
  28. extern struct icntmpltstruct *new_icn();
  29. extern struct grptmpltstruct *new_grp();
  30. extern struct pagestruct *new_pg();
  31. extern void readicon_i();
  32. extern struct filestruct *add_file();
  33. extern Boolean read_ascii();
  34. extern void ask_user_duplicate_icons(int dup_icn_cnt);
  35. extern void setChange();
  36.  
  37. float *version_read;
  38. float version = .05;
  39.     /* .02 had actual icon positions in the data file, 
  40.        .03 has indexices to an array of icon positions
  41.        .04 pages stored as num icons on the front and then the icon stuff,
  42.            num icons on the back and the icon stuff, groups also have a
  43.            cover color 
  44.     .05 added integer representing a help file to the
  45.        icon struct and the group struct   */
  46. Boolean old_02, old_03, old_04;
  47. Boolean append = FALSE;
  48. static int numiconblocks = 1;
  49. static iconblocksize = 1024;
  50. static int iconlimit = 1023;
  51.  
  52. struct indexlist **key_list;
  53. struct filestruct **file_list;
  54. struct icntmpltstruct **icon_list;
  55. int lastkey, lastfile, endicon;
  56.  
  57. struct icntmpltstruct **duplicate_icons;
  58. int max_dup;
  59. int dup_icn_cnt;
  60.  
  61. FILE *infp;
  62. FILE *outfp;
  63. char inbuf[70];
  64.    char nullchar = '\0';
  65.    char   newline = '\n';
  66.    char *thefile;   /* buffer for the whole file when I'm reading it */
  67.  
  68. int seticoncolor(int incolor)
  69. {
  70.    short pc1, pc2;
  71.    int outcolor;
  72.    int i;
  73.  
  74.    if (incolor >= 0)
  75.       {
  76.       outcolor = incolor + 10;
  77.       }
  78.    else
  79.       {
  80.       incolor = -incolor;
  81.       pc1 = incolor & 0xf;
  82.       pc2 = (incolor & 0xf0) >> 4;
  83.       if (pc1 == pc2)
  84.          {
  85.          outcolor = pc1 + 10;
  86.          }
  87.       else
  88.          {
  89.          if (pc2 > pc1)  /* switch the order */
  90.             {
  91.             incolor = pc1;
  92.             pc1 = pc2;
  93.             pc2 = incolor;
  94.             }
  95.          outcolor = 25;
  96.          for (i = 0; i < pc2; i++)
  97.             outcolor = outcolor + (15-i);
  98.          outcolor = outcolor + (pc1 - pc2);
  99.          }
  100.       }
  101.    return(outcolor);
  102. }
  103.  
  104. /************************************************************
  105. *
  106. * Read a WorkSpace icon file.
  107.  
  108. currently, anything that is not a number is made black. 
  109. iconcolor = -247, outlinecolor = 0
  110. *
  111. ************************************************************/
  112. int readicon_g(FILE *iconfp, struct icntmpltstruct *curicon, int cur_vertex)
  113. {
  114.    struct polylist *headpoly;
  115.    int bufndx;
  116.    char tmp[20];
  117.    int newpoly, nextpoly;
  118.    int vert_count;  /* count verts for this polygon*/
  119.    int start_vertex;
  120.    float xin, yin;
  121.    int closed;
  122.    int num_conv;
  123.    int numpoly;
  124.    int polycolor, linecolor;
  125.    short r1, r2, g1, g2, b1, b2;
  126.    int i,j;
  127.    int len;
  128.    float minx, maxx, miny, maxy;
  129.    Boolean gotcolor;
  130.    int first_vert;
  131.    float xscale, yscale, scalefactor;
  132.    float halfx, halfy;
  133.    float xtrans, ytrans;
  134.    float sizex, sizey;
  135.    int idx;
  136.  
  137.    if (icon_verts == NULL)
  138.       icon_verts = (MyPoint *)malloc(iconblocksize * sizeof(MyPoint));
  139.    first_vert = cur_vertex;
  140.    headpoly = curicon->poly;
  141.    curicon->geofile->icon = curicon;
  142.    minx = 100.0;
  143.    miny = 100.0;
  144.    maxx = -100.0;
  145.    maxy = -100.0;
  146.    nextpoly = 0;
  147.    while ( fgets(inbuf,60,iconfp) != NULL) 
  148.       {
  149. /* find the first char that is not a tab */
  150.       bufndx = 0;
  151.       len = strlen(inbuf);
  152.       while (bufndx < len+1 && inbuf[bufndx] == '\t')
  153.          {
  154.          bufndx++;
  155.          }
  156.       switch (inbuf[bufndx])
  157.          {
  158.          case '#':
  159.             break;
  160.          case 'b':
  161.             vert_count = 0;
  162.             start_vertex = cur_vertex;
  163.             strncpy(tmp, &(inbuf[bufndx]), 17);
  164.             if (strncmp(tmp, "bgnpolygon", 10) == 0)
  165.                {
  166.                newpoly = nextpoly;
  167.                ++nextpoly;
  168.                closed = 0;
  169.                headpoly[newpoly].line = -1;
  170.                headpoly[newpoly].type = 1;
  171.                }
  172.             else if (strncmp(tmp, "bgnoutlinepolygon", 17) == 0)
  173.                {
  174.                newpoly = nextpoly;
  175.                ++nextpoly;
  176.                closed = 1;
  177.                vert_count++;
  178.                headpoly[newpoly].type = 2;
  179.                }
  180.             else if (strncmp(tmp, "bgnline", 7) == 0)
  181.                {
  182.                newpoly = nextpoly;
  183.                ++nextpoly;
  184.                closed = 0;
  185.                headpoly[newpoly].poly = -1;
  186.                headpoly[newpoly].type = 3;
  187.                }
  188.             else if (strncmp(tmp, "bgnclosedline", 13) == 0)
  189.                {
  190.                newpoly = nextpoly;
  191.                ++nextpoly;
  192.                closed = 1;
  193.                headpoly[newpoly].poly = -1;
  194.                vert_count++;
  195.                headpoly[newpoly].type = 4;
  196.                }
  197.             break;
  198.          case 'e':
  199.             strncpy(tmp, &(inbuf[bufndx]), 17);
  200.             if (strncmp(tmp, "endpolygon", 10) == 0)
  201.                {
  202.                headpoly[newpoly].poly = polycolor;
  203.                }
  204.             else if (strncmp(tmp, "endline", 7) == 0)
  205.                {
  206.                headpoly[newpoly].line = polycolor;
  207.                }
  208.             else if (strncmp(tmp, "endclosedline", 13) == 0)
  209.                {
  210.                headpoly[newpoly].line = polycolor;
  211.                }
  212.             else if (strncmp(tmp, "endoutlinepolygon", 17) == 0)
  213.                {
  214.                headpoly[newpoly].poly = polycolor;
  215.               gotcolor = FALSE;
  216.               if ((num_conv = sscanf(&(inbuf[bufndx+18])," %d ",&linecolor))==1)
  217.                  gotcolor = TRUE;
  218.               else if (num_conv!=1 && strncmp(&(inbuf[bufndx+18]), "iconcolor", 9)==0)
  219.                  {
  220.                  gotcolor = TRUE;
  221.                  linecolor = -247;
  222.                  }
  223.               else if (num_conv!=1 && strncmp(&(inbuf[bufndx+18]), "outlinecolor", 12)==0)
  224.                  {
  225.                  gotcolor = TRUE;
  226.                  linecolor = 0;
  227.                  }
  228.               if (gotcolor)
  229.                  {
  230.                  headpoly[newpoly].line = seticoncolor(linecolor);
  231.                  }
  232.                }
  233.  
  234.             headpoly[newpoly].ndcs = (int *)malloc((vert_count+1)*sizeof(int) );
  235.             for (i = start_vertex, j = 0; i < cur_vertex; i++, j++)
  236.                {
  237.                headpoly[newpoly].ndcs[j] = i;
  238.                }
  239.             if (closed == 1)
  240.                headpoly[newpoly].ndcs[vert_count-1] = start_vertex;
  241.             headpoly[newpoly].ndcs[vert_count] = -1;
  242.  
  243.             break;
  244.          case 'c':   /* color */
  245.               gotcolor = FALSE;
  246.               if ((num_conv = sscanf(&(inbuf[bufndx+6])," %d ",&polycolor))==1)
  247.                  gotcolor = TRUE;
  248.               else if (num_conv!=1 && strncmp(&(inbuf[bufndx+6]), "iconcolor", 9)==0)
  249.                  {
  250.                  gotcolor = TRUE;
  251.                  polycolor = -247;
  252.                  }
  253.               else if (num_conv!=1 && strncmp(&(inbuf[bufndx+6]), "outlinecolor", 12)==0)
  254.                  {
  255.                  gotcolor = TRUE;
  256.                  polycolor = 0;
  257.                  }
  258.               if (gotcolor)
  259.                  {
  260.                  polycolor =  seticoncolor(polycolor);
  261. /* iconcolor (-247) becomes 117 */
  262.                  }
  263.             break;
  264.          case 'v':
  265.             {
  266.             strncpy(tmp, &(inbuf[bufndx]), 6);
  267.             if (strncmp(tmp, "vertex", 6) == 0)
  268.                {
  269.                   /*  The vertex data should be a string of the     */
  270.                   /*  form:  vertex(xx.x, yy.y).  Using atof, read  */
  271.                   /*  the substrings starting at idx 7, and at the  */
  272.                   /*  first character following the ",".  This is   */
  273.                   /*  faster than using sscanf.                     */
  274.                   idx = 7;
  275.                   while( inbuf[idx] != ',' ) idx++;
  276.                   xin = (float)atof( &(inbuf[bufndx+7]) );
  277.                   yin = (float)atof( &(inbuf[idx+1]) );
  278.  
  279.                   icon_verts[cur_vertex][0] = xin;
  280.                   icon_verts[cur_vertex][1] = yin;
  281.                   icon_verts[cur_vertex][2] = 0.0;
  282.                   if (icon_verts[cur_vertex][0] > maxx) 
  283.                      maxx = icon_verts[cur_vertex][0];
  284.                   if (icon_verts[cur_vertex][0] < minx) 
  285.                      minx = icon_verts[cur_vertex][0];
  286.                   if (icon_verts[cur_vertex][1] > maxy) 
  287.                      maxy = icon_verts[cur_vertex][1];
  288.                   if (icon_verts[cur_vertex][1] < miny) 
  289.                      miny = icon_verts[cur_vertex][1];
  290.                   ++cur_vertex;
  291.                   ++vert_count;
  292.                   if (cur_vertex > iconlimit)
  293.                      {
  294.                      numiconblocks++;
  295.                      icon_verts = (MyPoint *)realloc( (void *)icon_verts, numiconblocks *
  296.                              iconblocksize  * sizeof(MyPoint));
  297.                      iconlimit = numiconblocks * iconblocksize - 1;
  298.                      }
  299.                }
  300.             }
  301.             break;
  302.          default:
  303.             break;
  304.          }
  305.       } /* end of while fgets */
  306.     sizex = maxx - minx;
  307.     sizey = maxy - miny;
  308. /* do as michelle did, not as she said */
  309. /*     scalefactor = (sizex > sizey) ? 1.8 / sizex : 1.8 / sizey; */
  310.     scalefactor = (sizex > sizey) ? 1.6 / sizex : 1.6 / sizey; 
  311.     xtrans = 1.0 - ((maxx + minx) * scalefactor / 2.0);
  312. /* do as michelle did not as she said */
  313. /*    ytrans = 1.2375 - ((maxy + miny) * scalefactor / 2.0); */
  314.     ytrans = 1.1 - ((maxy + miny) * scalefactor / 2.0);
  315.     for (i = first_vert; i < cur_vertex; i++)
  316.     {
  317.     icon_verts[i][0] = (icon_verts[i][0] * scalefactor) + xtrans;
  318.     icon_verts[i][1] = (icon_verts[i][1] * scalefactor) + ytrans;
  319.     /* z is always 0 */
  320.     }
  321.     
  322.    return(cur_vertex);
  323.    }
  324.  
  325. /************************************************************
  326. *
  327. * Write the icons into the file.  The icons are stored as:
  328. *    a character representing the type of icon.
  329. *    a short associated with the demo name in the index
  330. *    a short as a pointer to the geo icon file name
  331. *    a short as a pointer to the img icon file name
  332. *    a short as a pointer to the help file name 2/18/93 .05
  333. *    a list of shorts (ended by -1) as pointers to the other files
  334. *    a short representing the number of keywords
  335. *    a short for each keyword.
  336. *    a string term. by nullchar for the alternate startstring 2/18/93 .05
  337. *
  338. ************************************************************/
  339. int write_icon(struct icntmpltstruct *iconptr)
  340. {
  341.    struct wordlist *wrdptr;
  342.    struct filelist *flptr;
  343.    int i;
  344.    int bytecount;
  345.    short none;
  346.    int length;
  347.   
  348.    none = -1;
  349.     /* type (geom/image) of icon */
  350.    bytecount = 0;
  351.    fwrite(&(iconptr->filetype),sizeof(char),1,outfp);
  352.    bytecount = bytecount + sizeof(char);
  353.     /* write name */
  354.    fwrite(&(iconptr->nameptr->num),sizeof(short),1,outfp);
  355.    bytecount = bytecount + sizeof(short);
  356.     /* write integers for pointers to files */
  357.    if (iconptr->geofile != NULL)
  358.       {
  359.       fwrite(&(iconptr->geofile->count),sizeof(short),1, outfp);
  360.       }
  361.    else
  362.       fwrite(&(none),sizeof(short),1, outfp);
  363.    bytecount = bytecount + sizeof(short);
  364.    if (iconptr->imgfile != NULL)
  365.       fwrite(&(iconptr->imgfile->count),sizeof(short),1, outfp);
  366.    else
  367.       fwrite(&(none),sizeof(short),1, outfp);
  368.    bytecount = bytecount + sizeof(short);
  369.  
  370.    if (iconptr->helpfile != NULL)
  371.       fwrite(&(iconptr->helpfile->count),sizeof(short),1, outfp);
  372.    else
  373.       fwrite(&(none),sizeof(short),1, outfp);
  374.    bytecount = bytecount + sizeof(short);
  375.  
  376.    flptr = iconptr->addtlfiles;
  377.    while(flptr != NULL)
  378.       {
  379.       if (flptr->file != NULL)
  380.          {
  381.          fwrite(&(flptr->file->count),sizeof(short),1, outfp);
  382.          bytecount = bytecount + sizeof(short);
  383.          }
  384.       flptr = flptr->next;
  385.       }
  386.     /* end the list of additional files with a negative one */
  387.    fwrite(&(none),sizeof(short),1, outfp);
  388.    bytecount = bytecount + sizeof(short);
  389.         /* write keywords */
  390.    fwrite(&(iconptr->numkey),sizeof(short),1,outfp);
  391.    bytecount = bytecount + sizeof(short);
  392.    wrdptr = iconptr->keywords;
  393.    for (i = 0; i < iconptr->numkey; i++)
  394.       {
  395.       fwrite(&(wrdptr->indexptr->num),sizeof(short),1,outfp);
  396.       bytecount = bytecount + sizeof(short);
  397.       wrdptr = wrdptr->next;
  398.       }
  399. /* write out the alternate start string  */
  400.    if (iconptr->alt_command != NULL)
  401.       {
  402.       length = strlen(curicon->alt_command);
  403.       fwrite(curicon->alt_command,sizeof(char),length,outfp);
  404.       bytecount = bytecount + length;
  405.       }
  406.    fwrite(&nullchar,sizeof(char),1,outfp);
  407.    bytecount++;
  408.  
  409.    fwrite(&newline,sizeof(char),1,outfp);
  410.    bytecount++;
  411.    return(bytecount);
  412. }
  413.  
  414. /************************************************************
  415. *
  416. * Reads the file buffer for each icon in the book.  Icons
  417. * are stored as:
  418. *    a character representing the type of icon.
  419. *    a short associated with the demo name in the index
  420. *    an integer as a pointer to the geo icon file name 8/21/91
  421. *    an integer as a pointer to the img icon file name 8/21/91
  422. *    a short as a pointer to the help file name 2/18/93 .05
  423. *    a list of integers (ended by -1) as pointers to the other files 8/21/91
  424. *    a short representing the number of keywords
  425. *    a short for each keyword.
  426. *    a string term. by nullchar for the alternate startstring 2/18/93 .05
  427. *
  428. ************************************************************/
  429. read_icons(int intofile, int endoficons)
  430. {
  431.    char *charptr;
  432.    char *end;
  433.    char *bc;
  434.    int iconcount;
  435.    short numkeys;
  436.    struct wordlist *wrdptr;
  437.    int i;
  438.    short j;
  439.    struct icntmpltstruct *curicon;
  440.    int filendx;
  441.    short indx;
  442.    struct filelist *lastfl, *flptr;
  443.    struct filestruct *fptr;
  444.    int kl_limit, kl_bc, kl_size, kl_count;
  445.    struct indexlist *tmpndxptr;
  446.    char tmpfiletype;
  447.    int length;
  448.    char tmpstor[10];
  449.  
  450.    dup_icn_cnt = 0;
  451.    max_dup = 32;
  452.    duplicate_icons = (struct icntmpltstruct **) malloc
  453.             ( max_dup* sizeof(struct icntmpltstruct *));
  454.    end = &( thefile[intofile+endoficons]);
  455.    bc = &( thefile[intofile] );
  456.    iconcount = 0;
  457.    kl_size = 50;
  458.    kl_limit = kl_size;
  459.    kl_count = 0;
  460.    kl_bc = 1;
  461.    icon_list = (struct icntmpltstruct **)malloc(kl_limit * sizeof(struct icntmpltstruct *) );
  462.    while (bc < end)
  463.       {
  464.       tmpfiletype = *bc;
  465.       bc++;
  466.       curicon = new_icn();
  467.       icon_list[kl_count] = curicon;
  468.       kl_count++;
  469.       if (kl_count == kl_limit)
  470.          {
  471.          kl_bc++;
  472.          kl_limit = kl_bc * kl_size;
  473.          icon_list = (struct icntmpltstruct **)realloc( (void *)icon_list,
  474.                     kl_limit * sizeof(struct icntmpltstruct *) );
  475.          }
  476.       if (firsticon == NULL)
  477.          firsticon = curicon;
  478.       else
  479.          lasticon->nexticntmplt = curicon;
  480.       lasticon = curicon;
  481.       curicon->ok = TRUE;
  482.       curicon->filetype = tmpfiletype;
  483.     /* read name */
  484.       for (i = 0; i < sizeof(short); i++)
  485.          tmpstor[i] = bc[i];
  486.       indx = *((short*)tmpstor);
  487.       bc += sizeof(short);
  488.       tmpndxptr = key_list[indx];
  489.       curicon->nameptr = tmpndxptr;
  490.       tmpndxptr->count++;
  491.       if (tmpndxptr != NULL && tmpndxptr->icon != NULL)
  492.          {
  493.          duplicate_icons[dup_icn_cnt] = curicon;
  494.          dup_icn_cnt++;
  495.          if (dup_icn_cnt == max_dup)
  496.             {
  497.             max_dup = max_dup + 32;
  498.             duplicate_icons = (struct icntmpltstruct **) realloc
  499.            ( (void *) duplicate_icons, max_dup* sizeof(struct icntmpltstruct *));
  500.             }
  501.          }
  502.       else
  503.          {
  504.          if (curicon->nameptr == NULL)
  505.             curicon->nameptr = add_keyword("dontknow");
  506.          else
  507.             curicon->nameptr->icon = curicon;
  508.          }
  509.     /* read files */
  510.     /* geo icon file */
  511.       for (i = 0; i < sizeof(short); i++)
  512.          tmpstor[i] = bc[i];
  513.       filendx = *((short*)tmpstor);
  514.       if (filendx >= 0)
  515.         {
  516.         curicon->geofile = file_list[filendx];
  517.         file_list[filendx]->occurences++;
  518.         }
  519.       bc += sizeof(short);
  520.     /* img icon file */
  521.       for (i = 0; i < sizeof(short); i++)
  522.          tmpstor[i] = bc[i];
  523.       filendx = *((short*)tmpstor);
  524.       if (filendx >= 0)
  525.         {
  526.         curicon->imgfile = file_list[filendx];
  527.         file_list[filendx]->occurences++;
  528.         }
  529.       bc += sizeof(short);
  530.       do_iconfiles(curicon);
  531.       if (!(old_02 || old_03 || old_04) )
  532.          {
  533.     /* help file */
  534.       for (i = 0; i < sizeof(short); i++)
  535.          tmpstor[i] = bc[i];
  536.          filendx = *((short*)tmpstor);
  537.          if (filendx >= 0)
  538.             {
  539.             curicon->helpfile = file_list[filendx];
  540.             file_list[filendx]->occurences++;
  541.             }
  542.          else
  543.             curicon->helpfile = NULL;
  544.          bc += sizeof(short);
  545.          }
  546.     /* additional files */
  547.       for (i = 0; i < sizeof(short); i++)
  548.          tmpstor[i] = bc[i];
  549.       filendx = *((short*)tmpstor);
  550.       lastfl = NULL;
  551.       curicon->ok = TRUE;
  552.       curicon->addtlfiles = NULL;
  553.       while (filendx >= 0 ) /*&& filendx < lastfile) */
  554.          {
  555.          flptr = (struct filelist *)malloc(sizeof(struct filelist) );
  556.          flptr->file = NULL;
  557.          flptr->next = NULL;
  558.             flptr->file = file_list[filendx];
  559.             file_list[filendx]->occurences++;
  560.             if (flptr->file == NULL || !(flptr->file->ok))
  561.                {
  562.                curicon->ok = FALSE;
  563.                }
  564.          if (lastfl == NULL)
  565.             {
  566.             curicon->addtlfiles = flptr;
  567.             lastfl = flptr;
  568.             }
  569.          else
  570.             {
  571.             lastfl->next = flptr;
  572.             lastfl = flptr;
  573.             }
  574.          lastfl->next = NULL;
  575.          bc += sizeof(short);
  576.       for (i = 0; i < sizeof(short); i++)
  577.          tmpstor[i] = bc[i];
  578.          filendx = *((short*)tmpstor);
  579.          }
  580.       bc += sizeof(short);
  581.     /* read number of keywords */
  582.       for (i = 0; i < sizeof(short); i++)
  583.          tmpstor[i] = bc[i];
  584.       curicon->numkey = *((short *)tmpstor);
  585.       bc += sizeof(short);
  586.     /* read keywords */
  587.       if (curicon->numkey > 0)
  588.          {
  589.          wrdptr=(struct wordlist *)malloc(sizeof(struct wordlist));
  590.          wrdptr->next = NULL;
  591.          wrdptr->indexptr = NULL;
  592.          curicon->keywords = wrdptr;
  593.       for (i = 0; i < sizeof(short); i++)
  594.          tmpstor[i] = bc[i];
  595.          indx = *((short*)tmpstor);
  596.          bc += sizeof(short);
  597.          if (indx >= 0 && indx < lastkey)
  598.             {
  599.             wrdptr->indexptr = key_list[indx];
  600.             key_list[indx]->count++;
  601.             }
  602.          if (wrdptr->indexptr != NULL)
  603.             index_add_demo(wrdptr->indexptr, curicon);
  604.          for (j = 1; j < curicon->numkey; j++)
  605.             {
  606.             if (wrdptr->indexptr != NULL)
  607.                {
  608.                wrdptr->next=(struct wordlist *)malloc(sizeof(struct wordlist));
  609.                wrdptr = wrdptr->next;
  610.                wrdptr->next = NULL;
  611.                wrdptr->indexptr = NULL;
  612.                }
  613.       for (i = 0; i < sizeof(short); i++)
  614.          tmpstor[i] = bc[i];
  615.             indx = *((short*)tmpstor);
  616.             bc += sizeof(short);
  617.             if (indx >= 0 && indx < lastkey)
  618.                {
  619.                wrdptr->indexptr = key_list[indx];
  620.                key_list[indx]->count++;
  621.                }
  622.             if (wrdptr->indexptr != NULL)
  623.                index_add_demo(wrdptr->indexptr, curicon);
  624. /* ERROR if the last keyword is not found  */
  625.             }
  626.          }
  627.     /* set xsize */
  628.       curicon->xsize = 1.0;
  629.     /* read alternate start string  */
  630.       if (!(old_02 || old_03 || old_04) )
  631.          {
  632.          length = strlen(bc);
  633.          if (length > 0)
  634.             { 
  635.             curicon->alt_command = (char *) malloc ( length + 1 );
  636.             strncpy(curicon->alt_command, bc, length+1);
  637.             }
  638.          else
  639.             curicon->alt_command = NULL;
  640.          bc+=(length+1);
  641.          }
  642.       bc++;  /* skip the newline */
  643.       ++iconcount;
  644.       }
  645.    numberoficons = numberoficons + iconcount; /* global */
  646.    for (i = kl_count; i < kl_limit; i++)
  647.       icon_list[i] = NULL;
  648.    endicon = kl_limit;
  649. }
  650.  
  651. Boolean check_start_string(int icon_num)
  652. {
  653.    int i;
  654.    int cmp_rslt;
  655.  
  656.    
  657. }
  658.  
  659. /************************************************************
  660. *
  661. * This routine reads the start strings.  They are stored 
  662. * in the file consecutively, and are associated with the
  663. * correct demo by position in the list.
  664. *
  665. ************************************************************/
  666. read_start_strings(int intofile, int endofss)
  667. {
  668.    int count, length;
  669.    char *bc, *end;
  670.    struct icntmpltstruct *curicon;
  671.  
  672.    bc = &( thefile[intofile] );
  673.    end = &( thefile[intofile +endofss]);
  674.    count = 0;
  675.    curicon = icon_list[count];
  676.    while (bc < end)
  677.       {
  678.       length = strlen(bc);
  679.       set_start_string( curicon, bc);
  680.       count++;
  681.       bc+=length; /* move over this start string */
  682.       bc++; /* skip the null character */
  683.       curicon = icon_list[count];
  684.       }
  685. }
  686.  
  687. /************************************************************
  688. *
  689. * Write out a page.  Each page is stored as:
  690. *    an integer -- the number of icons
  691. *    for each icon, the icon number (an integer)
  692. *    two floats -- the x and y position of the icon on the page
  693. *
  694. ************************************************************/
  695. write_page(struct pagestruct *pgptr)
  696. {
  697.    int bytecount;
  698.    int i;
  699.    struct iconstruct *tmpiconptr;
  700.    int side;
  701.  
  702.     /* write icon number and location */
  703.      /* front of page */
  704.    fwrite(&(pgptr->frontnumicons),sizeof(int),1,outfp);
  705.    bytecount = sizeof(int);
  706.    tmpiconptr = pgptr->fronticons;
  707.    for (i = 0; i < pgptr->frontnumicons; i++)
  708.       {
  709.       tmpiconptr->iconnum = tmpiconptr->iconptr->iconnum;
  710.   /* ERROR  don't really need the iconnum field in the iconstruct*/
  711.       fwrite(&(tmpiconptr->iconnum),sizeof(int),1,outfp);
  712.       bytecount = bytecount + sizeof(int);
  713.       fwrite(&(tmpiconptr->xposition_ndx),sizeof(short),1,outfp);
  714.       bytecount = bytecount+ sizeof(short);
  715.       fwrite(&(tmpiconptr->yposition_ndx),sizeof(short),1,outfp);
  716.       bytecount = bytecount+ sizeof(short);
  717.       tmpiconptr = tmpiconptr ->nexticon;
  718.       }
  719.  
  720.    fwrite(&(pgptr->backnumicons),sizeof(int),1,outfp);
  721.    bytecount = bytecount + sizeof(int);
  722.    tmpiconptr = pgptr->backicons;
  723.    for (i = 0; i < pgptr->backnumicons; i++)
  724.       {
  725.       tmpiconptr->iconnum = tmpiconptr->iconptr->iconnum;
  726.   /* ERROR  don't really need the iconnum field in the iconstruct*/
  727.       fwrite(&(tmpiconptr->iconnum),sizeof(int),1,outfp);
  728.       bytecount = bytecount + sizeof(int);
  729.       fwrite(&(tmpiconptr->xposition_ndx),sizeof(short),1,outfp);
  730.       bytecount = bytecount+ sizeof(short);
  731.       fwrite(&(tmpiconptr->yposition_ndx),sizeof(short),1,outfp);
  732.       bytecount = bytecount+ sizeof(short);
  733.       tmpiconptr = tmpiconptr ->nexticon;
  734.       }
  735.  
  736.    return(bytecount);
  737. }
  738.  
  739. /************************************************************
  740. *
  741. * Read all of the pages for a group.  Each page is stored as:
  742. *    an integer -- the number of icons
  743. *    for each icon, the icon number (an integer)
  744. *    two floats -- the x and y position of the icon on the page
  745. *
  746. ************************************************************/
  747. char *read_pages(char *pbc, int numpg, struct grptmpltstruct *grpptr)
  748. {
  749.    struct pagestruct *pgptr, *prevpgptr;
  750.    int i, j, k;
  751.    struct icntmpltstruct *curicon;
  752.    struct grpliststruct *glistptr;
  753.    struct iconstruct *tmpiconptr, *previconptr;
  754.    short xiconpos, yiconpos;
  755.    Boolean old_ok;
  756.    char tmpstor[10];
  757.  
  758.    prevpgptr = grpptr->lastpage;
  759.    old_ok = grpptr->ok;
  760.    grpptr->ok = FALSE;
  761.    for (i = 0; i < numpg; i++)
  762.       {
  763.       xiconpos = 0;
  764.       yiconpos = 3;
  765.       pgptr = new_pg();
  766.       if (grpptr->firstpage == NULL)
  767.          grpptr->firstpage = pgptr;
  768.       else
  769.          prevpgptr->nextpage = pgptr;
  770.       grpptr->lastpage = pgptr;
  771.       pgptr->prevpage = prevpgptr;
  772.       prevpgptr = pgptr;
  773.       pgptr->direction = 1;
  774.       for (k = 0; k < sizeof(int); k++)
  775.          tmpstor[k] = pbc[k];
  776.       pgptr->frontnumicons = *( (int *)tmpstor);
  777.       pbc+=sizeof(int);
  778.       previconptr = NULL;
  779.       for (j = 0; j < pgptr->frontnumicons; j++)
  780.          {
  781.          tmpiconptr = (struct iconstruct *)malloc(sizeof(struct iconstruct) );
  782.          tmpiconptr->nexticon = NULL;
  783.          if (pgptr->fronticons == NULL)
  784.             pgptr->fronticons = tmpiconptr;
  785.          else 
  786.             previconptr->nexticon = tmpiconptr;
  787.          previconptr = tmpiconptr;
  788.       for (k = 0; k < sizeof(int); k++)
  789.          tmpstor[k] = pbc[k];
  790.          tmpiconptr->iconnum = *( (int *) tmpstor);
  791.          pbc+=sizeof(int);
  792.          curicon = icon_list[tmpiconptr->iconnum];
  793.          (curicon->occurences)+=1;
  794.          tmpiconptr->iconptr = curicon;
  795.          tmpiconptr->ok = curicon->ok;
  796.          if (tmpiconptr->ok)
  797.             {
  798.             grpptr->ok = TRUE;
  799.             }
  800.          glistptr = (struct grpliststruct *)malloc(sizeof(struct grpliststruct) );
  801.          glistptr->next = NULL;
  802.          glistptr->prev = NULL;
  803.          if (curicon->grps == NULL)
  804.             curicon->grps = glistptr;
  805.          else
  806.             {
  807.             glistptr->next = curicon->grps;
  808.             curicon->grps = glistptr;
  809.             }
  810.          glistptr->grpptr = grpptr;
  811.          
  812.          if (old_02 == TRUE)
  813.             {
  814.             pbc+=sizeof(float); /* skip icon origin x */
  815.             pbc+=sizeof(float); /* skip icon origin y & rot_or y */
  816.             tmpiconptr->xposition_ndx = xiconpos;
  817.             tmpiconptr->yposition_ndx = yiconpos;
  818.             xiconpos++;
  819.             if (xiconpos > 4)
  820.                {
  821.                xiconpos = 0;
  822.                yiconpos--;
  823.                }
  824.             }
  825.          else 
  826.             {
  827.             for (k = 0; k < sizeof(short); k++)
  828.                tmpstor[k] = pbc[k];
  829.             tmpiconptr->xposition_ndx = *( (short *) tmpstor);
  830.             pbc+=sizeof(short);
  831.             for (k = 0; k < sizeof(short); k++)
  832.                tmpstor[k] = pbc[k];
  833.             tmpiconptr->yposition_ndx = *( (short *) tmpstor);
  834.             pbc+=sizeof(short);
  835.             }
  836.          tmpiconptr = tmpiconptr->nexticon;
  837.          }
  838.     /* version .04 might have icons on the backs of the pages */
  839.       if ( !old_02 && !old_03) 
  840.          {
  841.          for (k = 0; k < sizeof(int); k++)
  842.             tmpstor[k] = pbc[k];
  843.          pgptr->backnumicons = *( (int *)tmpstor);
  844.          pbc+=sizeof(int);
  845.          if (pgptr->backnumicons <= 0)
  846.             pgptr->backicons = NULL;
  847.          else
  848.             {
  849.             pgptr->backicons = NULL;
  850. /*
  851.             previconptr =  NULL;
  852. */
  853.             for (j = 0; j < pgptr->backnumicons; j++)
  854.                {
  855.                tmpiconptr = (struct iconstruct *)
  856.                          malloc(sizeof(struct iconstruct) );
  857.                tmpiconptr->nexticon = NULL;
  858.                if (pgptr->fronticons == NULL)
  859.                   pgptr->fronticons = tmpiconptr;
  860.                else 
  861.                   previconptr->nexticon = tmpiconptr;
  862.                previconptr = tmpiconptr;
  863.  
  864.          for (k = 0; k < sizeof(int); k++)
  865.             tmpstor[k] = pbc[k];
  866.                tmpiconptr->iconnum = *( (int *) tmpstor);
  867.                pbc+=sizeof(int);
  868.                curicon = icon_list[tmpiconptr->iconnum];
  869.                (curicon->occurences)+=1;
  870.                tmpiconptr->iconptr = curicon;
  871.                tmpiconptr->ok = curicon->ok;
  872.          if (tmpiconptr->ok)
  873.             {
  874.             grpptr->ok = TRUE;
  875.             }
  876.                glistptr = (struct grpliststruct *)malloc(sizeof(struct grpliststruct) );
  877.                glistptr->next = NULL;
  878.                glistptr->prev = NULL;
  879.                if (curicon->grps == NULL)
  880.                   curicon->grps = glistptr;
  881.                else
  882.                   {
  883.                   glistptr->next = curicon->grps;
  884.                   curicon->grps = glistptr;
  885.                   }
  886.                glistptr->grpptr = grpptr;
  887.       
  888.          for (k = 0; k < sizeof(short); k++)
  889.             tmpstor[k] = pbc[k];
  890.                   tmpiconptr->xposition_ndx = *( (short *) tmpstor);
  891.                   pbc+=sizeof(short);
  892.          for (k = 0; k < sizeof(short); k++)
  893.             tmpstor[k] = pbc[k];
  894.                   tmpiconptr->yposition_ndx = *( (short *) tmpstor);
  895.                   pbc+=sizeof(short);
  896.                tmpiconptr = tmpiconptr->nexticon;
  897.                }
  898.             }
  899.          }
  900.       else
  901.          {
  902.          pgptr->backicons = NULL;
  903.          pgptr->backnumicons = 0;
  904.          }
  905.       }
  906.    grpptr->lastpage = pgptr;
  907.    grpptr->ok = grpptr->ok && old_ok;
  908.    return(pbc);
  909. }
  910.  
  911. /************************************************************
  912. *
  913. * Write out a group.  Each group is stored as:
  914. *    a short -- the number of pages
  915. *    a short -- the number of the group name
  916. *    a short -- the type of artwork on the page (unused)
  917. *    3 floats -- the cover color (0 - 1.0)
  918. *    a short -- index for the help file 2/18/93  .05
  919. *    a short -- the number of keywords
  920. *    shorts -- for each keyword, its number in the index
  921. *
  922. ************************************************************/
  923. write_group(struct grptmpltstruct *grpptr)
  924. {
  925.    struct wordlist *wrdptr;
  926.    int i;
  927.    int bytecount;
  928.    short none;
  929.  
  930.    none = -1;
  931.    fwrite(&(grpptr->numpages),sizeof(short),1,outfp);
  932.    bytecount = sizeof(short);
  933.     /* write name */
  934.    fwrite(&(grpptr->nameptr->num),sizeof(short),1,outfp);
  935.    bytecount = bytecount + sizeof(short);
  936.  
  937.     /* type for group artwork */
  938.    fwrite(&(grpptr->arttype),sizeof(short),1,outfp);
  939.    bytecount = bytecount + sizeof(short);
  940.  
  941.     /* write cover color */
  942.    fwrite( &(grpptr->covercolor[0]), sizeof(float), 3, outfp);
  943.    bytecount = bytecount + 3 * sizeof(float);
  944.  
  945.     /* write index for help file */
  946.    if (grpptr->helpfile != NULL)
  947.       fwrite(&(grpptr->helpfile->count),sizeof(short),1, outfp);
  948.    else
  949.       fwrite(&(none),sizeof(short),1, outfp);
  950.    bytecount = bytecount + sizeof(short);
  951.  
  952.     /* write group keywords */
  953.    fwrite(&(grpptr->numkey),sizeof(short),1,outfp);
  954.    bytecount = bytecount + sizeof(short);
  955.    wrdptr = grpptr->keywords;
  956.    for (i = 0; i < grpptr->numkey; i++)
  957.       {
  958.       fwrite(&(wrdptr->indexptr->num),sizeof(short),1,outfp);
  959.       bytecount = bytecount + sizeof(short);
  960.       wrdptr = wrdptr->next;
  961.       }
  962.    return(bytecount);
  963. }
  964. /************************************************************
  965. *
  966. *  Make each group's list of icons continuous across page
  967. *  and page side boundaries.
  968. *
  969. ************************************************************/
  970. void fix_icon_pointers(struct grptmpltstruct *grpptr)
  971. {
  972.    struct pagestruct *pgptr;
  973.    struct iconstruct *tmpicn, *holdicon, *bicnptr, *ficnptr;
  974.  
  975.    if (grpptr->firstpage->backicons != NULL || grpptr->numpages > 1)
  976.       {
  977.       pgptr = grpptr->firstpage;
  978.       holdicon = NULL;
  979.       while (pgptr != NULL)
  980.          {
  981.          tmpicn = pgptr->fronticons;
  982.          if (holdicon != NULL)
  983.             holdicon->nexticon = tmpicn;
  984.     /* if there are no backicons, this loop will stop when 
  985.        tmpicn == NULL.  If there are, it will stop at
  986.        the end of the front page.  */
  987.          while (tmpicn != pgptr->backicons)
  988.             {
  989.             holdicon = tmpicn;
  990.             tmpicn = tmpicn->nexticon;
  991.             }
  992.          if (pgptr->backicons != NULL)
  993.             {
  994.             tmpicn = pgptr->backicons;
  995.             if (holdicon != NULL)
  996.                holdicon->nexticon = tmpicn;
  997.             if (pgptr->nextpage != NULL)
  998.                ficnptr = pgptr->nextpage->fronticons;
  999.             else
  1000.                ficnptr = NULL;
  1001.     /* if there is not a next page, this loop will stop 
  1002.        when tmpicn = NULL, If there is a next page, this
  1003.        loop will stop at the end of the backside of this page */
  1004.             while (tmpicn != ficnptr && tmpicn != NULL)
  1005.                {
  1006.                holdicon = tmpicn;
  1007.                tmpicn = tmpicn->nexticon;
  1008.                }
  1009.             }
  1010.          pgptr = pgptr->nextpage;
  1011.          }
  1012.       }
  1013. }
  1014.  
  1015. /************************************************************
  1016. *
  1017. * Read all the groups.  Each group is stored as:
  1018. *    a short -- the number of pages
  1019. *    a short -- the number of the group name
  1020. *    a short -- the type of artwork on the page (unused)
  1021. *    3 floats -- the cover color (0 - 1.0)
  1022. *    a short -- index for the help file 2/18/93  .05
  1023. *    a short -- the number of keywords
  1024. *    shorts -- for each keyword, its number in the index
  1025. *
  1026. ************************************************************/
  1027. read_groups(char *bc, char *end, char *pbc)
  1028. {
  1029.    struct grptmpltstruct *newgrpptr, *prevg;
  1030.    char *newword;
  1031.    struct wordlist *wrdptr, *prevptr, *lastptr;
  1032.    int count;
  1033.    int numnewgroups;
  1034.    int tmpnumpages;
  1035.    struct indexlist *tmpndxptr;
  1036.    struct grptmpltstruct *tmpgrp;
  1037.    short tmpnumkey;
  1038.    int indx;
  1039.    char tmpstor[10];
  1040.    int i;
  1041.  
  1042.    prevg = lastgroup;
  1043.    numnewgroups = 0;  
  1044.    while (bc < end)
  1045.       {
  1046.       for (i = 0; i < sizeof(short); i++)
  1047.          tmpstor[i] = bc[i];
  1048.       tmpnumpages = *( (short *)tmpstor);
  1049.       bc+=sizeof(short);
  1050.       for (i = 0; i < sizeof(short); i++)
  1051.          tmpstor[i] = bc[i];
  1052.       tmpndxptr = key_list[ *( (short *)tmpstor) ];
  1053.       bc+=sizeof(short);
  1054.         /* check to see if a group with this name already exists */
  1055.       if (tmpndxptr->group != NULL)
  1056.          {
  1057.          newgrpptr = tmpndxptr->group;
  1058.          pbc = read_pages(pbc, tmpnumpages, newgrpptr);
  1059.          newgrpptr->numpages = newgrpptr->numpages + tmpnumpages;
  1060.          fix_icon_pointers(newgrpptr);
  1061.          bc+=sizeof(short);  /* art type */
  1062.     /* skip over color if file version is >= .04 */
  1063.          if (!old_02 && !old_03)
  1064.             {
  1065.             bc+=sizeof(float);
  1066.             bc+=sizeof(float);
  1067.             bc+=sizeof(float);
  1068.             }
  1069.     /* helpfile */
  1070.     /* what to do if the new help file is different from the old one?  */
  1071.          if (!(old_02 || old_03 || old_04) )
  1072.             {
  1073.       for (i = 0; i < sizeof(short); i++)
  1074.          tmpstor[i] = bc[i];
  1075.             indx = *((short*)tmpstor);
  1076.             if (indx >= 0)
  1077.                {
  1078.                if (newgrpptr->helpfile == NULL)
  1079.                   {
  1080.                   newgrpptr->helpfile = file_list[indx];
  1081.                   file_list[indx]->occurences++;
  1082.                   }
  1083. /*
  1084.                else if (newgrpptr->helpfile != file_list[indx])
  1085.                   {
  1086.    ERROR  might want to notify user, or give them a chance to choose -
  1087.    ERROR which helpfile the group will use 
  1088.                   }
  1089. */
  1090.                }
  1091.             bc += sizeof(short);
  1092.             }
  1093.     /* keywords */
  1094.       for (i = 0; i < sizeof(short); i++)
  1095.          tmpstor[i] = bc[i];
  1096.          tmpnumkey = *( (short *) tmpstor);
  1097.          bc+=sizeof(short);
  1098.          if (tmpnumkey > 0)
  1099.             {
  1100.             if (newgrpptr->keywords == NULL)
  1101.                {
  1102.         /* do keywords the normal way */
  1103.                newgrpptr->numkey = tmpnumkey;
  1104.                count = 0;
  1105.                while (count < newgrpptr->numkey)
  1106.                   {
  1107.       for (i = 0; i < sizeof(short); i++)
  1108.          tmpstor[i] = bc[i];
  1109.                   indx = *((short*)tmpstor);
  1110.                   bc+=sizeof(short);
  1111.                   if (key_list[indx] != NULL)
  1112.                      {
  1113.                      if (newgrpptr->keywords == NULL)
  1114.                         {
  1115.                         wrdptr=(struct wordlist *)malloc(sizeof(struct wordlist));
  1116.                         newgrpptr->keywords = wrdptr;
  1117.                         }
  1118.                      else
  1119.                         {
  1120.                         wrdptr->next = (struct wordlist *)malloc(sizeof(struct wordlist));
  1121.                         wrdptr = wrdptr->next;
  1122.                         }
  1123.                      wrdptr->next = NULL;
  1124.                      wrdptr->indexptr = key_list[indx];
  1125.                      wrdptr->indexptr->count++;
  1126.                      index_add_group(wrdptr->indexptr, newgrpptr);
  1127.                      }
  1128.                   count++;
  1129.                   }
  1130.                }
  1131.             else
  1132.                {
  1133.         /* check each keyword to see if this group already uses it */
  1134.                count = 0;
  1135.                while (count < tmpnumkey)
  1136.                   {
  1137.       for (i = 0; i < sizeof(short); i++)
  1138.          tmpstor[i] = bc[i];
  1139.                   indx = *((short*)tmpstor);
  1140.                   bc+=sizeof(short);
  1141.                   if (key_list[indx] != NULL)
  1142.                      {
  1143.                      wrdptr = newgrpptr->keywords;
  1144.                      while (wrdptr != NULL && wrdptr->indexptr != key_list[indx])
  1145.                         {
  1146.                         prevptr = wrdptr;
  1147.                         wrdptr = wrdptr->next;
  1148.                         }
  1149.             /* if wrdptr == key_list[indx] don't do anything else */
  1150.                      if (wrdptr == NULL)
  1151.                         {
  1152.             /* this keyword is not already used by this group */
  1153.                         prevptr->next = (struct wordlist *)malloc(sizeof(struct wordlist));
  1154.                         wrdptr = prevptr->next;
  1155.                         wrdptr->next = NULL;
  1156.                         wrdptr->indexptr = key_list[indx];
  1157.                         wrdptr->indexptr->count++;
  1158.                         index_add_group(wrdptr->indexptr, newgrpptr);
  1159.                         }
  1160.                      }
  1161.                   count++;
  1162.                   }
  1163.                }
  1164.             }
  1165.          }
  1166.       else 
  1167.          {
  1168.       numnewgroups++;
  1169.       newgrpptr = new_grp();
  1170.       newgrpptr->ok = TRUE;
  1171.       if (firstgroup == NULL)
  1172.          {
  1173.          firstgroup = newgrpptr;
  1174.          }
  1175.       else
  1176.          {
  1177.          prevg -> nextgrp = newgrpptr;
  1178.          newgrpptr->prevgrp = prevg;
  1179.          }
  1180.       prevg = newgrpptr;
  1181.       lastgroup = newgrpptr;
  1182.       newgrpptr->numpages = tmpnumpages;
  1183.       pbc = read_pages(pbc, newgrpptr->numpages, newgrpptr);
  1184.       fix_icon_pointers(newgrpptr);
  1185.       newgrpptr->nameptr = tmpndxptr;
  1186.       if (newgrpptr->nameptr == NULL)
  1187.          newgrpptr->nameptr = add_keyword("dontknow");
  1188.       else
  1189.          newgrpptr->nameptr->count++;
  1190.       newgrpptr->nameptr->group = newgrpptr;
  1191.       for (i = 0; i < sizeof(short); i++)
  1192.          tmpstor[i] = bc[i];
  1193.       newgrpptr->arttype = *( (short *)tmpstor);
  1194.       bc+=sizeof(short);
  1195.         /* read the color if the version is >= .04 */
  1196.       if (!old_02 && !old_03)
  1197.          {
  1198.          for (i = 0; i < sizeof(float); i++)
  1199.             tmpstor[i] = bc[i];
  1200.          newgrpptr->covercolor[0] = *( (float *) tmpstor);
  1201.          bc+=sizeof(float);
  1202.          for (i = 0; i < sizeof(float); i++)
  1203.             tmpstor[i] = bc[i];
  1204.          newgrpptr->covercolor[1] = *( (float *) tmpstor);
  1205.          bc+=sizeof(float);
  1206.          for (i = 0; i < sizeof(float); i++)
  1207.             tmpstor[i] = bc[i];
  1208.          newgrpptr->covercolor[2] = *( (float *) tmpstor);
  1209.          bc+=sizeof(float);
  1210.          }
  1211.       else
  1212.          {
  1213.          newgrpptr->covercolor[0] = 1.0;
  1214.          newgrpptr->covercolor[1] = 0.0;
  1215.          newgrpptr->covercolor[2] = 0.0;
  1216.          }
  1217.     /* help file */
  1218.       if (!(old_02 || old_03 || old_04) )
  1219.          {
  1220.          for (i = 0; i < sizeof(short); i++)
  1221.             tmpstor[i] = bc[i];
  1222.          indx = *((short*)tmpstor);
  1223.          if (indx >= 0)
  1224.             {
  1225.             newgrpptr->helpfile = file_list[indx];
  1226.             file_list[indx]->occurences++;
  1227.             }
  1228.          bc += sizeof(short);
  1229.          }
  1230.         /* read all of the keywords */
  1231. /* the old dumb way of doing keywords 
  1232.          for (i = 0; i < sizeof(short); i++)
  1233.             tmpstor[i] = bc[i];
  1234.       newgrpptr->numkey = *( (short *) tmpstor);
  1235.       bc+=sizeof(short);
  1236.       if (newgrpptr->numkey > 0)
  1237.          {
  1238.          wrdptr=(struct wordlist *)malloc(sizeof(struct wordlist));
  1239.          newgrpptr->keywords = wrdptr;
  1240.          wrdptr->next = NULL;
  1241.          for (i = 0; i < sizeof(short); i++)
  1242.             tmpstor[i] = bc[i];
  1243.          wrdptr->indexptr = key_list[*((short*)tmpstor)];
  1244.          if (wrdptr->indexptr != NULL)
  1245.             {
  1246.             wrdptr->indexptr->count++;
  1247.             index_add_group(wrdptr->indexptr, newgrpptr);
  1248.             }
  1249.          bc+=sizeof(short);
  1250.          count = 1;
  1251.          while (count < newgrpptr->numkey)
  1252.             {
  1253.             if (wrdptr->indexptr != NULL)
  1254.                {
  1255.                wrdptr->next=(struct wordlist *)malloc(sizeof(struct wordlist));
  1256.                wrdptr = wrdptr->next;
  1257.                wrdptr->next = NULL;
  1258.                }
  1259.          for (i = 0; i < sizeof(short); i++)
  1260.             tmpstor[i] = bc[i];
  1261.             wrdptr->indexptr = find_keyword_int(*((short*)tmpstor));
  1262.             if (wrdptr->indexptr != NULL)
  1263.                {
  1264.                wrdptr->indexptr->count++;
  1265.                index_add_group(wrdptr->indexptr, newgrpptr);
  1266.                }
  1267.             bc+=sizeof(short);
  1268.             count++;
  1269.             }
  1270.          }
  1271. */
  1272.          for (i = 0; i < sizeof(short); i++)
  1273.             tmpstor[i] = bc[i];
  1274.       newgrpptr->numkey = *( (short *) tmpstor);
  1275.       bc+=sizeof(short);
  1276.       if (newgrpptr->numkey > 0)
  1277.          {
  1278.          count = 0;
  1279.          while (count < newgrpptr->numkey)
  1280.             {
  1281.          for (i = 0; i < sizeof(short); i++)
  1282.             tmpstor[i] = bc[i];
  1283.             indx = *((short*)tmpstor);
  1284.             bc+=sizeof(short);
  1285.             if (key_list[indx] != NULL)
  1286.                {
  1287.                if (newgrpptr->keywords == NULL)
  1288.                   {
  1289.                   wrdptr=(struct wordlist *)malloc(sizeof(struct wordlist));
  1290.                   newgrpptr->keywords = wrdptr;
  1291.                   }
  1292.                else
  1293.                   {
  1294.                   wrdptr->next = (struct wordlist *)malloc(sizeof(struct wordlist));
  1295.                   wrdptr = wrdptr->next;
  1296.                   }
  1297.                wrdptr->next = NULL;
  1298.                wrdptr->indexptr = key_list[indx];
  1299.                wrdptr->indexptr->count++;
  1300.                index_add_group(wrdptr->indexptr, newgrpptr);
  1301.                }
  1302.             count++;
  1303.             }
  1304.          }
  1305.          }
  1306.       }
  1307. /*
  1308.    lastgroup = newgrpptr;
  1309.    lastgroup->nextgrp = NULL;
  1310. */
  1311.    numberofgroups = numberofgroups + numnewgroups;
  1312.    numberofbooks = numberofgroups;
  1313.    initbookpos();
  1314. }
  1315.  
  1316. #define ST 0
  1317. #define IF 1
  1318. #define KW 2
  1319. #define I 3
  1320. #define P 4
  1321. #define G 5
  1322. /************************************************************
  1323. *
  1324. * Write out the file.
  1325. *    The file begins with a 'v' and the version number.
  1326. *    Then there are six integers that represent the
  1327. * length, in bytes, of each section of the file.
  1328. *    The first section contains the startstrings (command
  1329. * lines for all of the demos).  Each string is written to
  1330. * the file followed by a null character.
  1331. *    Next are the icon filenames. THey are also written
  1332. * out as strings with a null character between them.  The
  1333. * filenames and the start strings are one per demo, so they
  1334. * are associated with the correct demo by their position in the list.
  1335. *    Then all of the keywords are written out separated
  1336. * by a null character.
  1337. *    Then each icon in the book is written out.
  1338. *    Then each page is written out.
  1339. *    Then each groups is written out.
  1340. *
  1341. ************************************************************/
  1342. write_file(char *outfilename)
  1343. {
  1344.    struct grptmpltstruct *tmpgrp;
  1345.    struct indexlist *tmpndx;
  1346.    struct pagestruct *tmppg;
  1347.    struct filestruct *fileptr;
  1348.    int i;
  1349.    short count;
  1350.    int length;
  1351.    short bclength = 6;
  1352.    int bytecount[6];
  1353.    struct icntmpltstruct *curicon;
  1354.    char v = 'v';
  1355.         /*  bytecount :
  1356.             0    startstrings
  1357.             1    keywords
  1358.             2    icons
  1359.             3    pages
  1360.             4    groups  */
  1361.       if (ASCII)
  1362.          {
  1363. /*
  1364. printf(" writing ascii file \n");
  1365. */
  1366.          write_ascii(outfilename);
  1367.          }
  1368.       else
  1369.          {
  1370.    for ( i = 0; i < bclength; i++)
  1371.        bytecount[i] = 0;
  1372.    bytecount[ST] = sizeof(char) + sizeof(float) + sizeof(int) * bclength;
  1373.    if ( (outfp = fopen(outfilename,"w")) == NULL) 
  1374.       {
  1375.       sprintf(msgstring, "Could not open file \n%s\nfor output ...\nFile will not be written.",outfilename);
  1376.       DialogType = 1;
  1377.       popup_Message();
  1378.       }
  1379.    else
  1380.       {
  1381.     /* write file format version number */
  1382.    fwrite(&v,sizeof(char), 1,outfp);
  1383.    fwrite(&version,sizeof(float), 1,outfp);
  1384.  
  1385.         /* leave room for the offsets into the file (bytecount) */
  1386.    fwrite(bytecount,sizeof(int), bclength,outfp);
  1387.  
  1388.     /* write all of the startstrings */
  1389.    length = strlen(firsticon->startstring);
  1390.    fwrite(firsticon->startstring,sizeof(char), length,outfp);
  1391.    bytecount[IF] = length;
  1392.    firsticon->iconnum = 0;
  1393.    curicon = firsticon->nexticntmplt;
  1394.    for (i = 1; i < numberoficons; i++)
  1395.       {
  1396.       fwrite(&nullchar,sizeof(char),1,outfp);
  1397.       bytecount[IF]++;
  1398.       length = strlen(curicon->startstring);
  1399.       fwrite(curicon->startstring,sizeof(char),length,outfp);
  1400.       bytecount[IF] = bytecount[IF] + length;
  1401.        /* renumber icons while i'm at it */
  1402.       curicon->iconnum = i;
  1403.       curicon = curicon->nexticntmplt;
  1404.       }
  1405.    fwrite(&nullchar,sizeof(char),1,outfp);
  1406.    bytecount[IF]++;
  1407.         /* write all of the filenames  8/21/91 this now includes the
  1408.            icon filenames as well as the file names for executables,
  1409.            data files, and other files that are needed to run a demo. 
  1410.            If a tape is made, all of the files that the book knows
  1411.            about will be written out to tape.
  1412.        2/18/93  This now includes the help file for showcase and
  1413.            the directory for the source code.  */
  1414.    fileptr = headfile;
  1415.    bytecount[KW] = 0;
  1416.    i = 0;
  1417.    while (fileptr != NULL)
  1418.       {
  1419.       length = strlen(fileptr->name);
  1420.       if (length > 0)
  1421.          {
  1422.          fwrite(fileptr->name, sizeof(char), length, outfp);
  1423.          fwrite(&nullchar,sizeof(char),1,outfp);
  1424.          bytecount[KW] = bytecount[KW] + length + 1;
  1425.          fileptr->count = i;
  1426.          i++;
  1427.          }
  1428.       fileptr = fileptr->next;
  1429.       }
  1430.    fwrite(&i, sizeof(int),1,outfp);  /* write out the number of files */
  1431.    bytecount[KW] +=sizeof(int);
  1432.     /* write out all of the keywords */
  1433.    count = 0;
  1434.    length = strlen(Index->string);
  1435.    fwrite(Index->string,sizeof(char),length,outfp);
  1436.    bytecount[I] = length;
  1437.    Index->num = count;
  1438.    tmpndx = Index->next;
  1439.    while (tmpndx != NULL)
  1440.       {
  1441.       fwrite(&nullchar,sizeof(char),1,outfp);
  1442.       bytecount[I]++;
  1443.       length = strlen(tmpndx->string);
  1444.       fwrite(tmpndx->string,sizeof(char),length,outfp);
  1445.       bytecount[I] = bytecount[I] + length;
  1446.       tmpndx->num = ++count;
  1447.       tmpndx = tmpndx->next;
  1448.       }
  1449.    fwrite(&nullchar,sizeof(char),1,outfp);
  1450.    bytecount[I]++;
  1451.     /* for each icon, call write_icon */
  1452.    bytecount[P] = 0;
  1453.    curicon = firsticon;
  1454.    while (curicon != NULL)
  1455.       {
  1456.       bytecount[P] = bytecount[P] + write_icon(curicon);
  1457.       curicon = curicon->nexticntmplt;
  1458.       }
  1459.     /* write out all of the pages */
  1460.    bytecount[G] = 0;
  1461.    tmpgrp = firstgroup;
  1462.    tmppg = tmpgrp->firstpage;
  1463.    while (tmpgrp != NULL)
  1464.       {
  1465.       bytecount[G] = bytecount[G] + write_page(tmppg);
  1466.       tmppg = tmppg->nextpage;
  1467.       if (tmppg == NULL)
  1468.          {
  1469.          tmpgrp = tmpgrp->nextgrp;
  1470.          if (tmpgrp != NULL) tmppg = tmpgrp->firstpage;
  1471.          }
  1472.       }
  1473.     /* for each group, call write_group */
  1474.    tmpgrp = firstgroup;
  1475.    while (tmpgrp != NULL)
  1476.       {
  1477.       write_group(tmpgrp);
  1478.       tmpgrp = tmpgrp->nextgrp;
  1479.       }
  1480.         /* go back to the begining and write out the bytecount again */
  1481.    rewind(outfp);
  1482.    fseek(outfp, (sizeof(char) + sizeof(float)), SEEK_SET);
  1483.    fwrite(bytecount,sizeof(int), bclength,outfp);
  1484.    fclose(outfp);
  1485.    sprintf(msgstring, "\nSaved the book file\n%s\n", FileName);
  1486.    popup_Message();
  1487.       }
  1488.       }  /* end of else for if ASCII */
  1489. }
  1490.  
  1491. /************************************************************
  1492. *
  1493. * Put all of the demos in alphabetical order by name.
  1494. *
  1495. ************************************************************/
  1496. alphabetize()
  1497. {
  1498.    struct icntmpltstruct *curicon, *previcon, *beforethis, *thisicon, *nextone;
  1499.    Boolean changed, done;
  1500.    struct grptmpltstruct *grpptr;
  1501.    struct indexlist *tmpname;
  1502.  
  1503.    changed = TRUE;
  1504.    while (changed)
  1505.       {
  1506.       changed = FALSE;
  1507.       thisicon = firsticon;
  1508.       beforethis = NULL;
  1509.       while (thisicon != NULL)
  1510.          {
  1511.          nextone = thisicon->nexticntmplt;
  1512.          curicon = thisicon->nexticntmplt;
  1513.          previcon = thisicon;
  1514.          while (curicon != NULL && strcasecmp(thisicon->nameptr->string,curicon->nameptr->string)<=0)
  1515.             {
  1516.             previcon = curicon;
  1517.             curicon = curicon->nexticntmplt;
  1518.             }
  1519.          if (curicon != NULL)   
  1520.             {
  1521.             changed = TRUE;
  1522.             if (thisicon == firsticon)
  1523.                firsticon = curicon;
  1524.             else
  1525.                beforethis->nexticntmplt = curicon;
  1526.             if (previcon != NULL)
  1527.                previcon->nexticntmplt = curicon->nexticntmplt;
  1528.             curicon->nexticntmplt = thisicon;
  1529.             nextone = thisicon;
  1530.             thisicon = curicon;
  1531.             }
  1532.          else
  1533.             {
  1534.             beforethis = thisicon;
  1535.             thisicon = thisicon->nexticntmplt;
  1536.             }
  1537.          }
  1538.       }
  1539.    tmpname = find_keyword("Master Index");
  1540.    grpptr = tmpname->group;
  1541.    if (grpptr != NULL)
  1542.       group_setup(firsticon,0, grpptr);
  1543. }
  1544.  
  1545. /************************************************************
  1546. *
  1547. * Read a book file.  First the entire file is read into a
  1548. * buffer.  Then the buffer is read.
  1549. *    The file begins with a 'v' and the version number.
  1550. *    Then there are six integers that represent the
  1551. * length, in bytes, of each section of the file.
  1552. *    The first section contains the startstrings (command
  1553. * lines for all of the demos).  Each string is written to
  1554. * the file followed by a null character.
  1555. *    Next are the icon filenames. They are also written
  1556. * out as strings with a null character between them.  The
  1557. * filenames are two per demo and the start strings are one
  1558. * per demo, so they are associated with the correct demo by
  1559. * their position in the list.
  1560. *    Then all of the keywords are written out separated
  1561. * by a null character.
  1562. *    Then each icon in the book is written out.
  1563. *    Then each page is written out.
  1564. *    Then each groups is written out.
  1565. *
  1566. ************************************************************/
  1567. read_file(char *filename)
  1568. {
  1569.    int numicons, numgroups;
  1570.    int i,j,filendx;
  1571.    int *bytecount; /* 6 entries to count bytes in thefile */
  1572.    long totalbytes;
  1573.    int numread;
  1574.    char *start, *key;
  1575.    int count, length;
  1576.    char *pbeg, *beg, *end;
  1577.    char v;
  1578.    Boolean FILEERR;
  1579.    struct indexlist *ndxptr;
  1580. float time1, time2;
  1581.    struct filestruct *fptr, *prevfptr;
  1582.    Boolean done;
  1583.    struct grptmpltstruct *grpptr;
  1584.    int acc_ret;
  1585.    char *fname;
  1586.    float tt1, tt2;
  1587.    int kl_bc, kl_size, kl_limit, kl_count;
  1588.    char *tmpstor;
  1589.    int filecount;
  1590.  
  1591.    append = FALSE;
  1592.    clock_sec(&time1);
  1593.    if (firsticon != NULL)
  1594.       {
  1595.       append = TRUE;
  1596.       setChange(TRUE);
  1597.       write_ascii("/usr/tmp/demobook_tmp.ascii");
  1598.       }
  1599.    if ( (infp = fopen(filename,"r")) == NULL) 
  1600.       {
  1601.       sprintf(msgstring, "Could not open file\n%s\nfor input ... \n",filename);
  1602.       DialogType = 1;
  1603. /*
  1604.       popup_Message();
  1605. */
  1606.       message_waiting = TRUE;
  1607.       }
  1608.    else
  1609.       {
  1610.    fseek(infp, 0L, SEEK_END);
  1611.    totalbytes = ftell(infp);
  1612.    rewind(infp);
  1613.    if (totalbytes > 0) {
  1614.       thefile = (char *)malloc(totalbytes+1);
  1615.       thefile[totalbytes] = '\0';
  1616.    }
  1617.    else
  1618.       {  
  1619.       thefile = NULL;
  1620.       sprintf(msgstring, "\nError:  file length.\nFile %s",filename);
  1621.       DialogType = 1;
  1622. /*
  1623.       popup_Message();
  1624. */
  1625.       message_waiting = TRUE;
  1626.       }
  1627.    if (thefile != NULL)
  1628.       {
  1629. /* Do not display the working dialog message, for now */
  1630. /*
  1631.       sprintf(msgstring, "\nReading in Book File ...\n");
  1632.       UxPopupInterface(create_Working(), no_grab);
  1633.       handleMotifInterfaceEvents();
  1634. */
  1635.       FILEERR = TRUE;
  1636.       numread = fread(thefile, sizeof(char), totalbytes, infp);
  1637.       v = thefile[0];
  1638.       tmpstor = (char *)malloc(sizeof(float) );
  1639.       for (i = 0; i < sizeof(float); i++)
  1640.          tmpstor[i] = thefile[i+1];
  1641.       version_read = (float *)malloc(sizeof(float) );
  1642.       *version_read = *(float *)(&(tmpstor[0]));
  1643.       if (v != 'v')
  1644.          {
  1645.          if (!(ASCII = read_ascii(thefile, totalbytes)))
  1646.             {
  1647.          sprintf(msgstring, "\nError:  File is not recognized.\nFile <%s>", filename);
  1648.          DialogType = 1;
  1649. /*
  1650.          popup_Message();
  1651. */
  1652.          message_waiting = TRUE;
  1653.             }
  1654.          }
  1655.       else  /* v == 'v' this prob is a demobook binary file*/
  1656.          {
  1657.          FILEERR = FALSE;
  1658.          if (*version_read > version)
  1659.             {
  1660.             sprintf(msgstring, "Datafile %s\nis newer than the executable.",filename);
  1661. /*
  1662.             popup_Message();
  1663. */
  1664.             message_waiting = TRUE;
  1665.             FILEERR = TRUE;
  1666.             }
  1667.          else 
  1668.             {
  1669.             old_02 = FALSE;
  1670.             old_03 = FALSE;
  1671.             old_04 = FALSE;
  1672.             if (*version_read != version)
  1673.                {
  1674.                if (*version_read < 0.025)  /* == .02 */
  1675.                   old_02 = TRUE;
  1676.                else if (*version_read < 0.035) /* == .03 */
  1677.                   old_03 = TRUE;
  1678.                else 
  1679.                   old_04 = TRUE;
  1680.            sprintf(msgstring, "File %s\nis in the old format.\nSave the file so that it will \nthen be in the new format.", filename);
  1681. /*
  1682.            popup_Message();
  1683. */
  1684.            message_waiting = TRUE;
  1685.                }
  1686.             }
  1687. /* old way */
  1688. /*
  1689.  bytecount = (int *)(void *)&(thefile[sizeof(char)+sizeof(float)]); 
  1690. printf("old bytecount test %d %d %d %d %d \n", bytecount[0], bytecount[1], bytecount[2], bytecount[3], bytecount[4]);
  1691. */
  1692. /* new way under 5.0 */
  1693.          tmpstor = (char *)realloc((void *)tmpstor, (G+1)*sizeof(int) );
  1694.          for (i = 0; i < (G+1)*sizeof(int); i++)
  1695.             tmpstor[i] = thefile[i+sizeof(char)+sizeof(float)];
  1696.          bytecount = (int *) malloc ((G+1)*sizeof(int) );
  1697.          /* test bytecount */
  1698.          for (i = 0 ; i <= G; i ++)
  1699.             {
  1700.             bytecount[i] = *(int *)(void *)&(tmpstor[i*sizeof(int)]);
  1701.             if (bytecount[i] > totalbytes)
  1702.                FILEERR = TRUE;
  1703.             }
  1704. /*
  1705. printf("new bytecount test %d %d %d %d %d %d \n", bytecount[0], bytecount[1], bytecount[2], bytecount[3], bytecount[4], bytecount[5]);
  1706. */
  1707.          } /*  end of else for v != 'v' */
  1708.       if (!FILEERR)
  1709.          {
  1710.     /* startstrings */
  1711.       start = thefile+bytecount[ST];
  1712.     /* read the filenames */
  1713.       filendx = bytecount[ST] + bytecount[IF] + bytecount[KW];
  1714.       filendx = filendx - sizeof(int);
  1715.       for (i = 0; i < sizeof(int); i++)
  1716.          tmpstor[i] = thefile[i+filendx];
  1717.       filecount = *(int *)(&tmpstor[0]);   /* this is the number of files in the book */
  1718.       filendx = bytecount[ST] + bytecount[IF];
  1719.       file_list = (struct filestruct **)malloc(filecount * sizeof(struct filestruct *) );
  1720.       kl_count = 0;
  1721.       for (j = 0; j < filecount; j++)
  1722.          {
  1723.          fptr = add_file(&(thefile[filendx]));
  1724.          fptr->occurences--;  
  1725.          file_list[kl_count] = fptr;
  1726.          kl_count++;
  1727.          length = strlen(&(thefile[filendx]));
  1728.          filendx = filendx+length+1;  /* string & nullchar */
  1729.          }
  1730.      if (headfile == NULL)
  1731.         {
  1732.         sprintf(msgstring, " error allocating space for files \n exiting program \n");
  1733.     DialogType = 1;
  1734. /*
  1735.         popup_Message();
  1736. */
  1737.         message_waiting = TRUE;
  1738.         exit(1);
  1739.         }
  1740.     /* read all of the keywords */
  1741.       kl_size = 50;
  1742.       key_list = (struct indexlist **)malloc(kl_size * sizeof(struct indexlist *) );
  1743.       kl_limit = kl_size;
  1744.       kl_count = 0;
  1745.       kl_bc = 1;
  1746.       key = thefile+bytecount[ST] + bytecount[IF] + bytecount[KW];
  1747.     /* count is actually a running total of the bytes used by each word */
  1748.       count = 0;
  1749.       while (count < bytecount[I])
  1750.          {
  1751.          length = strlen(key);
  1752.          ndxptr = add_keyword(key);
  1753.             /* add_keyword bumps the count up one. We don't want to
  1754.                do this until we actually use the keyword  */
  1755.          ndxptr->count--;
  1756.          key_list[kl_count] = ndxptr;
  1757.          kl_count++;
  1758.          if (kl_count == kl_limit)
  1759.             {
  1760.             kl_bc++;
  1761.             kl_limit = kl_size*kl_bc;
  1762.             key_list = (struct indexlist **)realloc((void *)key_list, 
  1763.                          kl_limit * sizeof (struct indexlist *) );
  1764.             }
  1765.          count = count + length+1;
  1766.          key = key +length+1;
  1767.          }
  1768.       for (i = kl_count; i < kl_limit; i++)
  1769.          key_list[i] = NULL;
  1770.       lastkey = kl_limit;
  1771.     /* icons are in the file next */
  1772.       count = bytecount[ST]+bytecount[IF]+bytecount[KW]+bytecount[I];
  1773.       read_icons(count,bytecount[P]);
  1774.       read_start_strings(bytecount[ST], bytecount[IF]);
  1775.     /* read groups */
  1776.       beg = thefile + bytecount[ST]+bytecount[IF]+bytecount[KW]+bytecount[I]+bytecount[P]+bytecount[G];
  1777.       pbeg = thefile + bytecount[ST]+bytecount[IF]+bytecount[KW]+bytecount[I]+bytecount[P];
  1778.       end = thefile + totalbytes;
  1779.       read_groups(beg, end, pbeg);
  1780. /*
  1781.       curgroup = firstgroup;
  1782. */
  1783.       grpptr = firstgroup;
  1784.       done = FALSE;
  1785.          ask_user_duplicate_icons(dup_icn_cnt);
  1786.       setup_all_groups();
  1787.       check_index();
  1788.          }
  1789.       else  /* FILEERR */
  1790.          {
  1791.          if (!ASCII)
  1792.             {
  1793.          if (v == 'v' && *version_read != version)
  1794.             {
  1795.             sprintf(msgstring, "\nError:  File has the wrong version number.\nFile <%s>", filename);
  1796.         DialogType = 1;
  1797. /*
  1798.             popup_Message();
  1799. */
  1800.             message_waiting = TRUE;
  1801.             }
  1802.          else
  1803.             {
  1804.             sprintf(msgstring, "\nError:  File is not recognized.\nFile <%s>", filename);
  1805.         DialogType = 1;
  1806. /*
  1807.             popup_Message();
  1808. */
  1809.             message_waiting = TRUE;
  1810.             }
  1811.             }
  1812.          }
  1813. /* The working dialog message is not displayed, for now */
  1814. /*
  1815.         UxPopdownInterface(Working);
  1816.         handleMotifInterfaceEvents();
  1817.     curgroup = NULL;
  1818. */
  1819.       }
  1820.    free(thefile);
  1821.    free(version_read);
  1822.    free(tmpstor);
  1823.    if (!ASCII)
  1824.       free(bytecount);
  1825.    fclose(infp);
  1826.       }
  1827.    clock_sec(&time2);
  1828.    if (append)
  1829.       alphabetize();
  1830.    check_files();
  1831. #ifdef HideMenu
  1832.    if (!append)
  1833.       fix_file_buttons();
  1834. #endif
  1835. }
  1836.  
  1837. void tar_files()
  1838. {
  1839.  
  1840.     struct filestruct *tmpptr;
  1841.     char *mystring;
  1842.     int total_size, st_length;
  1843.     int cur_length, block_size;
  1844.  
  1845.     block_size = 1024;
  1846.     mystring = (char *)malloc(block_size * sizeof(char));
  1847.     cur_length = block_size;
  1848.  
  1849.     tmpptr = headfile;
  1850.     
  1851.     total_size = 0;
  1852.     strcpy(mystring,"tar c /usr/demos/bin/demobook /usr/demos/data/demobook ");
  1853.     strcat(mystring,FileName);
  1854.     strcat(mystring," ");
  1855.     strcat(mystring,"/usr/demos/.login /usr/demos/.cshrc /usr/demos/.xsession ");
  1856.     strcat(mystring,"/usr/demos/.X* /usr/demos/.chestrc /usr/demos/.workspace ");
  1857.     strcat(mystring,"/usr/demos/button* /usr/demos/Application ");
  1858.     strcat(mystring,"/usr/demos/Performance /usr/demos/Tools ");
  1859.     strcat(mystring,"/usr/demos/.m* ");
  1860.     total_size = strlen(mystring);
  1861.     
  1862.     while (tmpptr != NULL)
  1863.       {
  1864.     st_length = strlen(tmpptr->name);
  1865.     total_size = total_size + st_length + 1;
  1866.     strcat(mystring,tmpptr->name);
  1867.     strcat(mystring," ");
  1868.     tmpptr = tmpptr->next;
  1869.     if (total_size >= cur_length)
  1870.            {
  1871.            cur_length = cur_length + block_size;
  1872.            mystring = (char *) realloc( (void *) mystring, cur_length);
  1873.            }
  1874.    }
  1875.       strcat(mystring," &");
  1876.       system(mystring);
  1877.       free(mystring);
  1878. }
  1879.  
  1880. Boolean match_color(colorA, colorB)
  1881.     float colorA[3], colorB[3];
  1882. {
  1883. /*
  1884.     printf("colorA = %.2f %.2f %.2f     colorB = %.2f %.2f %.2f\n", 
  1885.      colorA[0], colorA[1], colorA[2], colorB[0], colorB[1], colorB[2]);
  1886. */
  1887.  
  1888.     if ((colorA[0] == colorB[0]) &&
  1889.         (colorA[1] == colorB[1]) &&
  1890.         (colorA[2] == colorB[2]))
  1891.         return(TRUE);
  1892.     else
  1893.         return(FALSE);
  1894. }
  1895.